package edu.uc.labs.MobilePrinting.PrintUtils;

import edu.uc.labs.MobilePrinting.Configurator;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import javax.xml.parsers.*;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

/**
 * An XML Parser for Printer Configurations
 * 
 * @author Matthew Silbernagel
 */
public class PrinterParser {
	private static Logger logger = Configurator.LOGGER;

	/**
	 * Constructs a parser that can parse Printer Configurations
	 */
	public PrinterParser() throws ParserConfigurationException {
		DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
		builder = dbfactory.newDocumentBuilder();
		XPathFactory xpfactory = XPathFactory.newInstance();
		path = xpfactory.newXPath();

	}

	/**
	 * Parses an XML file containing a printer list
	 * 
	 * @param fileName
	 *            the name of the file
	 * @return an array list containing all printers in the XML file
	 */
	public ArrayList<Printer> parse(String fileName) throws SAXException,
			IOException, XPathExpressionException {
		File f = new File(fileName);
		if (!f.exists()) {
			logger.debug("PrinterParser:  The file to parse, " + fileName
					+ ", doesn't exist...");
			buildXMLFile(f);
		}

		logger.debug("now Parsing " + f.getAbsolutePath());
		Document doc = builder.parse(f);

		ArrayList<Printer> printers = new ArrayList<Printer>();
		int printerCount = Integer.parseInt(path.evaluate(
				"count(/CONFIGURATIONS/PRINTERS/PRINTER)", doc));
		for (int i = 1; i <= printerCount; i++) {
			String name = path.evaluate("/CONFIGURATIONS/PRINTERS/PRINTER[" + i
					+ "]/NAME", doc);
			String server = path.evaluate("/CONFIGURATIONS/PRINTERS/PRINTER["
					+ i + "]/SERVER", doc);
			String queue = path.evaluate("/CONFIGURATIONS/PRINTERS/PRINTER["
					+ i + "]/QUEUE", doc);
			String ppd = path.evaluate("/CONFIGURATIONS/PRINTERS/PRINTER[" + i
					+ "]/DRIVER", doc);
			String zone = path.evaluate("/CONFIGURATIONS/PRINTERS/PRINTER[" + i
					+ "]/ZONE", doc);
			String location = path.evaluate("/CONFIGURATIONS/PRINTERS/PRINTER["
					+ i + "]/LOCATION", doc);
			Printer p = new Printer(name, queue, server, ppd, location);
			p.setZone(zone);
			printers.add(p);
		}
		if (!printers.isEmpty()) {
			Configurator.setZone(printers.get(0).getZone());
		}
		return printers;
	}

	public static void buildXMLFile(File file) throws IOException {
		logger.debug("Looks like the file " + file.getAbsolutePath()
				+ " doesn't exist." + " Creating an empty XML file...");
		FileWriter fstream = new FileWriter(file);
		BufferedWriter out = new BufferedWriter(fstream);
		out.write("<?xml version='1.0'?>\n");
		out.write("<CONFIGURATIONS>\n" + "\t<COMPUTER>\n" + "\t\t<IP>  </IP>\n"
				+ "\t\t<SUBNET>  </SUBNET>\n" + "\t</COMPUTER>\n"
				+ "\t<PRINTERS>\n" + "\t</PRINTERS>\n" + "</CONFIGURATIONS>\n");
		out.close();
		logger.debug("Created the xml file");
	}

	private DocumentBuilder builder;
	private XPath path;
}
